#include <stdlib.h>
#include <stdio.h>

/* define list */
struct list_node
{
	struct list_node *prev;
	struct list_node *next;
};

typedef struct list_node list;
typedef struct list_node list_head;
typedef struct list_node *list_ptr;

void init_list( list *l )
{
	l->prev = l->next = l;
}

void add_list( list *l, list *new )
{
	l->next->prev = new;
	new->next = l->next;
	new->prev = l;
	l->next = new;
}

void add_list_end( list *l, list *new )
{
	add_list( l->prev, new );
}

int empty_list( const list *l )
{
	return l->next == l;
}

void del_list( list *cur )
{
	cur->next->prev = cur->prev;
	cur->prev->next = cur->next;
}

#ifndef offsetof
#define offsetof( type, member ) ((int)&(((type *)0)->member))
#endif

#define get_list_entry( type_ptr, node_ptr, member ) (typeof(type_ptr))((char *)(node_ptr) - (offsetof( typeof( *(type_ptr) ), member) ) )
#define for_each_entry( p, head_ptr, member ) \
	if( !empty_list( head_ptr ) ) \
		for( p = get_list_entry( (p), (head_ptr)->next, member ); &(p)->member != (head_ptr); (p) = get_list_entry( (p), (p)->member.next, member ) )


struct test_t
{
	int i;
	char c;
	list_head l;
};

struct test2_t
{
	double v;
	list_head l;
	const char *name;
};

int main( int argc, char *argv[] )
{
	list_head l;
	init_list( &l );

	struct test_t *pt;
	int i = 0;
	for( i = 0; i < 10; i++ ) {
		pt = (struct test_t *)malloc( sizeof( struct test_t) );
		pt->i = i;
		add_list( &l, &pt->l );
	}

	for_each_entry( pt, &l, l ) { 
		if( pt->i % 2 )
			del_list( &pt->l );
		printf( "%d\n", pt->i );
	}
	for_each_entry( pt, &l, l ) { 
		printf( "%d\n", pt->i );
	}

	struct test2_t *pt2;
	list_head l2;
	init_list( &l2 );
	for( i = 0; i < 10; i++ ) {
		pt2 = (struct test2_t *)malloc( sizeof( struct test2_t) );
		pt2->v = i * 1.1;
		add_list( &l2, &pt2->l );
	}

	for_each_entry( pt2, &l2, l ) { 
		printf( "%f\n", pt2->v );
	}
	return 0;
}

